package com.eslag.rpc.transport.socket.server;

import com.eslag.rpc.handler.RequestHandler;
import com.eslag.rpc.entity.RpcRequest;
import com.eslag.rpc.entity.RpcResponse;
import com.eslag.rpc.registry.ServiceRegistry;
import com.eslag.rpc.serializer.CommonSerializer;
import com.eslag.rpc.transport.socket.util.ObjectReader;
import com.eslag.rpc.transport.socket.util.ObjectWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.Socket;

/**
 * 处理RpcRequest的工作线程：
 *      从从ServiceRegistry 获取到提供服务的对象后，就会把 RpcRequest 和服务对象直接交给 RequestHandler 去处理
 *      ，反射等过程被放到了 RequestHandler 里。
 *
 *       三种创建线程的方法：1. new Thread() 2. 实现Runnable接口中的run()方法 3. 实现Callable接口中的run()方法
 */
public class SocketRequestHandlerThread implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(SocketRequestHandlerThread.class);

    private Socket socket;
    private RequestHandler requestHandler;
    private CommonSerializer serializer;

    public SocketRequestHandlerThread(Socket socket, RequestHandler requestHandler, CommonSerializer serializer) {
        this.socket = socket;
        this.requestHandler = requestHandler;
        this.serializer = serializer;
    }

    @Override
    public void run() {
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()) {
            // 获取客户端发来的请求
            RpcRequest rpcRequest = (RpcRequest) ObjectReader.readObject(inputStream);
            // 利用反射获得接口名
            String interfaceName = rpcRequest.getInterfaceName();
            // 在服务注册中心寻找接口名对应的服务
            // 调用requestHandler来处理请求
            Object result = requestHandler.handle(rpcRequest);
            // 写

            ObjectWriter.writeObject(outputStream, result, serializer);
        } catch (IOException e) {
            logger.error("调用或发送时有错误发生：", e);
        }
    }

}